/*
 * Copyright 2022-2027 中国信息通信研究院云计算与大数据研究所
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 
package com.service.impl;

import java.math.BigDecimal;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import com.common.constant.AccountConstant;
import com.common.constant.ChkuplogConstant;
import com.common.constant.ParamConstant;
import com.common.constant.TrancfgConstant;
import com.common.constant.UniformityConstant;
import com.localMapper.ParamcfgMapper;
import com.mapper.ChkuplogMapper;
import com.mapper.UniformityMapper;
import com.pojo.Chkuplog;
import com.pojo.Paramcfg;
import com.pojo.Tranlist;
import com.pojo.TranlistCount;
import com.pojo.Tranlog;
import com.service.UniformityService;

@Service
@Scope("prototype")
public class UniformityServiceImpl extends Thread implements UniformityService{

    @Autowired
    private UniformityMapper uniformityMapper;
    @Autowired
    private ChkuplogMapper chkuplogMapper;
    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;
    @Autowired
    private ParamcfgMapper paramcfgMapper;
    private BigDecimal afterAccountBale;
    private String process_id = "";
    private final Logger logger = LoggerFactory.getLogger(UniformityServiceImpl.class); 
    
    @Override
	public void run() {
    	logger.info("一致性检测线程启动了");
        Paramcfg paramcfg = paramcfgMapper.getParamByName(ParamConstant.PARAM_START_UNIFORMITY);
        if(UniformityConstant.UNIFORMITY_START_UNIFORMITY.equals(paramcfg.getParam_value())) {
    		uniformityCheck(afterAccountBale);
        }else {
        	logger.error("跳过一致性检测");
        }
    	logger.info("一致性检测线程结束了");
	}

    /**
     * 一致性检查
     * @param beforeAccountBale
     * @param runnum
     */
	private void uniformityCheck(BigDecimal beforeAccountBale) {
    	//account测试前计算总额
		BigDecimal afterAccountBale = uniformityMapper.sumAccount();
    	if(afterAccountBale==null) {
    		afterAccountBale = BigDecimal.ZERO;
    	}
    	BigDecimal incressBale = uniformityMapper.sumIncressAccount(process_id);
    	if(incressBale==null) {
    		incressBale = BigDecimal.ZERO;
    	}
    	BigDecimal temp = afterAccountBale.subtract(beforeAccountBale);
    	if(temp.compareTo(incressBale)!=0) {
    		logger.info(" UniformityServiceImpl uniformityCheck account总额 不一致 ");
        	insertChkuplog(new Chkuplog(ChkuplogConstant.CHKUPLOG_TYPE_C,System.currentTimeMillis()+"",AccountConstant.ACCOUNT_TRAN_FAILURE," UniformityServiceImpl uniformityCheck account总额 不一致 "));
        	return;
    	}
    	List<TranlistCount> sumTranlistCountList = uniformityMapper.sumTranlistCount();
    	if(sumTranlistCountList!=null&&sumTranlistCountList.size()==2) {
    		TranlistCount accountFrom = sumTranlistCountList.get(0);
    	    TranlistCount accountTo = sumTranlistCountList.get(1);
    	    if(!(accountFrom.getTranlist_total().doubleValue()==accountTo.getTranlist_total().doubleValue())) {
        		logger.info(" UniformityServiceImpl uniformityCheck 借贷金额总额不一致 ");
            	insertChkuplog(new Chkuplog(ChkuplogConstant.CHKUPLOG_TYPE_C,System.currentTimeMillis()+"",AccountConstant.ACCOUNT_TRAN_FAILURE," UniformityServiceImpl uniformityCheck 借贷金额总额不一致 "));
            	return;
    	    }
    	}
    	Integer branchCount = uniformityMapper.tranlogBranchCount();
    	Integer branchCountHistory = uniformityMapper.tranlogHistoryBranchCount();
    	if(branchCountHistory==null) {
    		branchCountHistory = 0;
    	}
    	if(branchCount!=null&&branchCount>0) {
    		if(branchCount.intValue()!=branchCountHistory.intValue()) {
    			logger.info(" UniformityServiceImpl uniformityCheck 网点序列号不一致 ");
            	insertChkuplog(new Chkuplog(ChkuplogConstant.CHKUPLOG_TYPE_C,System.currentTimeMillis()+"",AccountConstant.ACCOUNT_TRAN_FAILURE," UniformityServiceImpl uniformityCheck 网点序列号不一致 "));
            	return;
    		}
    	}
    	Tranlog tranlogTransfer = new Tranlog();
    	tranlogTransfer.setTranlog_trancfgid(TrancfgConstant.TRANCFG_ACCOUNTS_TRANSFER);
    	tranlogTransfer.setTranlog_success(AccountConstant.ACCOUNT_TRAN_SUCCESS);
    	tranlogTransfer.setTranlog_fld1(process_id);
    	Integer tranlogTransferSuccessCount = uniformityMapper.tranlogCount(tranlogTransfer);
    	if(tranlogTransferSuccessCount==null) {
    		tranlogTransferSuccessCount = 0;
    	}
    	Tranlist param = new Tranlist();
    	param.setTranlist_fld1(TrancfgConstant.TRANCFG_ACCOUNTS_TRANSFER);
    	Integer tranlistTransferCount = uniformityMapper.tranlistCount(param);
    	if(tranlistTransferCount==null) {
    		tranlistTransferCount = 0;
    	}
    	if(!(tranlistTransferCount.intValue()==tranlogTransferSuccessCount.intValue()*2)) {
    		logger.info(" UniformityServiceImpl uniformityCheck tranlog转账业务成功记录不是tranlist记录2倍 ");
        	insertChkuplog(new Chkuplog(ChkuplogConstant.CHKUPLOG_TYPE_C,System.currentTimeMillis()+"",AccountConstant.ACCOUNT_TRAN_FAILURE," UniformityServiceImpl uniformityCheck UniformityServiceImpl uniformityCheck tranlog转账业务成功记录不是tranlist记录2倍 "));
        	return;
    	}
    	
    	Tranlog tranlogSalary = new Tranlog();
    	tranlogSalary.setTranlog_trancfgid(TrancfgConstant.TRANCFG_ACCOUNTS_SALARY);
    	tranlogSalary.setTranlog_success(AccountConstant.ACCOUNT_TRAN_SUCCESS);
    	tranlogSalary.setTranlog_fld1(process_id);
    	Integer tranlogSalarySuccessCount = uniformityMapper.tranlogCount(tranlogSalary);
    	if(tranlogSalarySuccessCount==null) {
    		tranlogSalarySuccessCount = 0;
    	}
    	param.setTranlist_fld1(TrancfgConstant.TRANCFG_ACCOUNTS_SALARY);
    	param.setTranlist_dcdir(AccountConstant.TRANLIST_D);
    	Integer tranlistSalaryCount = uniformityMapper.tranlistCount(param);
    	if(tranlistSalaryCount==null) {
    		tranlistSalaryCount = 0;
    	}
    	if(!(tranlistSalaryCount.intValue()==tranlogSalarySuccessCount.intValue())) {
    		logger.info(" UniformityServiceImpl uniformityCheck tranlog代发工资贷方tranlist数量不等于tranlog数量  ");
        	insertChkuplog(new Chkuplog(ChkuplogConstant.CHKUPLOG_TYPE_C,System.currentTimeMillis()+"",AccountConstant.ACCOUNT_TRAN_FAILURE," UniformityServiceImpl uniformityCheck tranlog代发工资贷方tranlist数量不等于tranlog数量  "));
        	return;
    	}
		logger.info(" UniformityServiceImpl uniformityCheck success ");
    	insertChkuplog(new Chkuplog(ChkuplogConstant.CHKUPLOG_TYPE_C,System.currentTimeMillis()+"",AccountConstant.ACCOUNT_TRAN_SUCCESS,""));
	}


	/**
	 * 插入列表
	 * @param chkuplog
	 */
    public void insertChkuplog(Chkuplog chkuplog) {
    	TransactionStatus transactionStatus = null;
    	try {
    		transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
    		chkuplogMapper.insertChkuplog(chkuplog);
    		logger.info(" UniformityServiceImpl insertChkuplog  success ");
        	dataSourceTransactionManager.commit(transactionStatus);//提交
		} catch (Exception e) {
			logger.error(" UniformityServiceImpl insertChkuplog  rollback e {}" ,e);
	    	dataSourceTransactionManager.rollback(transactionStatus);
		}
	}

	public BigDecimal getAfterAccountBale() {
		return afterAccountBale;
	}

	public void setAfterAccountBale(BigDecimal afterAccountBale) {
		this.afterAccountBale = afterAccountBale;
	}

	public String getProcess_id() {
		return process_id;
	}

	public void setProcess_id(String process_id) {
		this.process_id = process_id;
	}
    
    
}